package com.social.servlet;

import com.social.dao.UserDAO;
import com.social.model.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import javax.servlet.annotation.MultipartConfig;

@WebServlet("/register")
@MultipartConfig(
    fileSizeThreshold = 1024 * 1024, // 1MB 内存缓存阈值，超过则写入临时文件
    maxFileSize = 5 * 1024 * 1024,   // 单个文件最大 5MB
    maxRequestSize = 50 * 1024 * 1024 // 请求总大小最大 50MB（包含多个文件和表单数据）
)
public class RegisterServlet extends HttpServlet {
    private static final String UPLOAD_DIR = "avatars"; // 头像存储目录（位于Web应用根目录下）
    private static final String DEFAULT_ERROR = "register.jsp?error=3"; // 上传失败

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        User user = new User();

        // 处理文件上传
        Part avatarPart = request.getPart("avatar");
        if (avatarPart != null && avatarPart.getSize() > 0) {
            String fileName = saveFile(avatarPart);
            user.setAvatar(fileName);
        } else {
            // 使用默认头像（可选）
            user.setAvatar("default_avatar.png");
        }

        // 处理其他表单字段
        String nickname = request.getParameter("nickname");
        String phone = request.getParameter("phone");
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        String birthdateStr = request.getParameter("birthdate");
        String gender = request.getParameter("gender");

        // 验证并保存用户
        UserDAO userDAO = new UserDAO();
        
        // 增加唯一性校验
        if (!userDAO.isNicknameUnique(nickname)) {
                response.sendRedirect("register.jsp?error=1");
                return;
            }
            if (!userDAO.isPhoneUnique(phone)) {
                response.sendRedirect("register.jsp?error=2");
                return;
            }
            if (!userDAO.isEmailUnique(email)) {
                response.sendRedirect("register.jsp?error=3");
                return;
            }
        // 设置用户属性
        user.setNickname(nickname);
        user.setPhone(phone);
        user.setEmail(email);
        user.setPassword(md5(password));
        user.setBirthdate(java.sql.Date.valueOf(birthdateStr));
        user.setGender(gender);

        if (userDAO.insertUser(user)) {
            response.sendRedirect("login.jsp"); // 注册成功
        } else {
            response.sendRedirect("register.jsp?error=2"); // 数据库错误
        }
    }

    private String saveFile(Part part) throws IOException {
        String fileName = getFileName(part);
        String uploadPath = getServletContext().getRealPath("/") + UPLOAD_DIR;
        Path directory = Paths.get(uploadPath);
        if (!Files.exists(directory)) {
            Files.createDirectories(directory);
        }
        Path filePath = directory.resolve(fileName);
        try (InputStream inputStream = part.getInputStream()) {
            Files.copy(inputStream, filePath);
        }
        return UPLOAD_DIR + "/" + fileName; // 存储相对路径到数据库
    }

    private String getFileName(Part part) {
        String originalFilename = part.getSubmittedFileName();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            return "unknown.jpg"; // 兜底默认名
        }

        // 分离文件名和扩展名
        int dotIndex = originalFilename.lastIndexOf(".");
        String extension = dotIndex != -1 ? originalFilename.substring(dotIndex) : "";

        // 生成唯一文件名（UUID + 扩展名）
        String uniqueFilename = UUID.randomUUID().toString() + extension;
        return uniqueFilename;
    }

    private String md5(String input) {
        // 保持MD5加密逻辑不变
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("register.jsp");
    }
}